package com.xb.loan.cashier.biz.task;

import com.xb.loan.cashier.biz.dao.bean.CashierEncashBatch;
import com.xb.loan.cashier.biz.util.ZooKeeperHelper;
import com.xb.loan.util.StringUtils;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.List;

/**
 * 第三方提现任务
 */
public abstract class ThirdEncashTask extends BaseTask {

    private static Logger loggger = LoggerFactory.getLogger(ThirdEncashTask.class);
    
    protected CashierEncashBatch cashierEncashBatch;
    
    public ThirdEncashTask(){}
    public ThirdEncashTask(CashierEncashBatch cashierEncashtask){
        this.cashierEncashBatch = cashierEncashtask;
    }
    
    public void setCashierEncashBatch(CashierEncashBatch cashierEncashBatch) {
        this.cashierEncashBatch = cashierEncashBatch;
    }
    
    @Override
    public void execute() {
        String path = null;
        try {
            if(cashierEncashBatch==null){
                return;
            }
            // 相同的批次号不能同时被执行
            path = isBatchExecuting(cashierEncashBatch.getBatchId());
            if(StringUtils.isBlank(path)){
                loggger.info("第三方提现，该批次正在执行中，返回。 batchId="+cashierEncashBatch==null?null:cashierEncashBatch.getBatchId());
                return;
            }
            
            doExecute();
        } catch (Exception e) {
            loggger.warn("第三方提现失败 batchId="+cashierEncashBatch==null?null:cashierEncashBatch.getBatchId(), e);
        } finally {
            if(StringUtils.isNotBlank(path)){
                removeBatchDir(path);
            }
        }
        
    }
    
    // 删除临时文件
    private void removeBatchDir(String path) {
        ZooKeeper zk = ZooKeeperHelper.getZookeeper(null);
        try {
            Stat stat = zk.exists(path, false);
            if(stat!=null){
                zk.delete(path, -1);
            }
            path = path.substring(0, path.lastIndexOf("/"));
            stat = zk.exists(path, false);
            if(stat!=null){
                zk.delete(path, -1);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }
    }

    private String isBatchExecuting(String batchId) {
        String path = null;
        try {
            ZooKeeper zk = ZooKeeperHelper.getZookeeper(null);
            String root = ZooKeeperHelper.ROOT_PATH_CASHIER_ENCASH_BATCH;
            Stat s = zk.exists(root, false);
            if (s == null) {
                zk.create(root, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            }
            root = root+"/batchid_"+batchId;
            s = zk.exists(root, false);
            if (s == null) {
                zk.create(root, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            }
            path = zk.create(root + "/lock_" , new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
            List<String> list = zk.getChildren(root, false);
            String[] nodes = list.toArray(new String[list.size()]);
            Arrays.sort(nodes);
            if(!path.equals(root+"/"+nodes[0])){
                path =  null;
            }
        } catch (Exception e) {
            path = null;
        }
        return path;
    }

    protected abstract void doExecute() throws Exception;
    
}
